Cleaning up
[andmenj-acm.git] / 11448 - Who said crisis / bigint-2007.07.07 / BigInteger.cc
blobba4918000eebac4933b45ac9fa2ec16c49785308
1 /*
2 * Matt McCutchen's Big Integer Library
3 */
5 #include "BigInteger.hh"
7 // MANAGEMENT
9 // Assignment operator
10 void BigInteger::operator =(const BigInteger &x) {
11 // Calls like a = a have no effect
12 if (this == &x)
13 return;
14 // Copy sign
15 sign = x.sign;
16 // Copy the rest
17 BigUnsigned::operator =(x);
20 // Constructor from an array of blocks and a sign
21 BigInteger::BigInteger(const Blk *b, Index l, Sign s) : BigUnsigned(b, l) {
22 switch (s) {
23 case zero:
24 case positive:
25 case negative:
26 sign = (len == 0) ? zero : s;
27 break;
28 default:
29 throw "BigInteger::BigInteger(Blk *, Index, Sign): Invalid sign";
33 // Constructor from a BigUnsigned and a sign
34 BigInteger::BigInteger(const BigUnsigned &x, Sign s) : BigUnsigned(x) {
35 switch (s) {
36 case zero:
37 case positive:
38 case negative:
39 sign = (len == 0) ? zero : s;
40 break;
41 default:
42 throw "BigInteger::BigInteger(Blk *, Index, Sign): Invalid sign";
47 * The steps for construction of a BigInteger
48 * from an integral value x are as follows:
49 * 1. If x is zero, create an empty BigInteger and stop.
50 * 2. Allocate a one-block number array.
51 * 3. If x is positive (or of an unsigned type), set the
52 * sign of the BigInteger to positive.
53 * 4. If x is of a signed type and is negative, set the
54 * sign of the BigInteger to negative.
55 * 5. If x is of a signed type, convert x (or -x if x < 0)
56 * to the unsigned type of the same length.
57 * 6. Expand x (or the result of step 5) to a Blk,
58 * and store it in the number array.
60 * See remarks in `BigUnsigned.cc' and `NumberlikeArray.hh'
61 * about new handling of zero-length arrays.
64 BigInteger::BigInteger(unsigned long x) {
65 if (x == 0)
66 sign = zero; // NumberlikeArray did the rest
67 else {
68 cap = 1;
69 blk = new Blk[1];
70 sign = positive;
71 len = 1;
72 blk[0] = Blk(x);
76 BigInteger::BigInteger(long x) {
77 if (x > 0) {
78 cap = 1;
79 blk = new Blk[1];
80 sign = positive;
81 len = 1;
82 blk[0] = Blk(x);
83 } else if (x < 0) {
84 cap = 1;
85 blk = new Blk[1];
86 sign = negative;
87 len = 1;
88 blk[0] = Blk(-x);
89 } else
90 sign = zero;
93 BigInteger::BigInteger(unsigned int x) {
94 if (x == 0)
95 sign = zero;
96 else {
97 cap = 1;
98 blk = new Blk[1];
99 sign = positive;
100 len = 1;
101 blk[0] = Blk(x);
105 BigInteger::BigInteger(int x) {
106 if (x > 0) {
107 cap = 1;
108 blk = new Blk[1];
109 sign = positive;
110 len = 1;
111 blk[0] = Blk(x);
112 } else if (x < 0) {
113 cap = 1;
114 blk = new Blk[1];
115 sign = negative;
116 len = 1;
117 blk[0] = Blk(-x);
118 } else
119 sign = zero;
122 BigInteger::BigInteger(unsigned short x) {
123 if (x == 0)
124 sign = zero;
125 else {
126 cap = 1;
127 blk = new Blk[1];
128 sign = positive;
129 len = 1;
130 blk[0] = Blk(x);
134 BigInteger::BigInteger(short x) {
135 if (x > 0) {
136 cap = 1;
137 blk = new Blk[1];
138 sign = positive;
139 len = 1;
140 blk[0] = Blk(x);
141 } else if (x < 0) {
142 cap = 1;
143 blk = new Blk[1];
144 sign = negative;
145 len = 1;
146 blk[0] = Blk(-x);
147 } else
148 sign = zero;
151 // CONVERTERS
153 * The steps for conversion of a BigInteger to an
154 * integral type are as follows:
155 * 1. If the BigInteger is zero, return zero.
156 * 2. If the BigInteger is positive:
157 * 3. If it is more than one block long or its lowest
158 * block has bits set out of the range of the target
159 * type, throw an exception.
160 * 4. Otherwise, convert the lowest block to the
161 * target type and return it.
162 * 5. If the BigInteger is negative:
163 * 6. If the target type is unsigned, throw an exception.
164 * 7. If it is more than one block long or its lowest
165 * block has bits set out of the range of the target
166 * type, throw an exception.
167 * 8. Otherwise, convert the lowest block to the
168 * target type, negate it, and return it.
171 namespace {
172 // These masks are used to test whether a Blk has bits
173 // set out of the range of a smaller integral type. Note
174 // that this range is not considered to include the sign bit.
175 const BigUnsigned::Blk lMask = ~0 >> 1;
176 const BigUnsigned::Blk uiMask = (unsigned int)(~0);
177 const BigUnsigned::Blk iMask = uiMask >> 1;
178 const BigUnsigned::Blk usMask = (unsigned short)(~0);
179 const BigUnsigned::Blk sMask = usMask >> 1;
182 BigInteger::operator unsigned long() const {
183 switch (sign) {
184 case zero:
185 return 0;
186 case positive:
187 if (len == 1)
188 return blk[0];
189 else
190 throw "BigInteger operator unsigned long() const: Value is too big for an unsigned long";
191 case negative:
192 throw "BigInteger operator unsigned long() const: Cannot convert a negative integer to an unsigned type";
193 default:
194 throw "BigInteger: Internal error";
198 BigInteger::operator long() const {
199 switch (sign) {
200 case zero:
201 return 0;
202 case positive:
203 if (len == 1 && (blk[0] & ~lMask) == 0)
204 return long(blk[0]);
205 else
206 throw "BigInteger operator long() const: Value is too big for a long";
207 case negative:
208 if (len == 1 && (blk[0] & ~lMask) == 0)
209 return -long(blk[0]);
210 else
211 throw "BigInteger operator long() const: Value is too big for a long";
212 default:
213 throw "BigInteger: Internal error";
217 BigInteger::operator unsigned int() const {
218 switch (sign) {
219 case zero:
220 return 0;
221 case positive:
222 if (len == 1 && (blk[0] & ~uiMask) == 0)
223 return (unsigned int)(blk[0]);
224 else
225 throw "BigInteger operator unsigned int() const: Value is too big for an unsigned int";
226 case negative:
227 throw "BigInteger operator unsigned int() const: Cannot convert a negative integer to an unsigned type";
228 default:
229 throw "BigInteger: Internal error";
233 BigInteger::operator int() const {
234 switch (sign) {
235 case zero:
236 return 0;
237 case positive:
238 if (len == 1 && (blk[0] & ~iMask) == 0)
239 return int(blk[0]);
240 else
241 throw "BigInteger operator int() const: Value is too big for an int";
242 case negative:
243 if (len == 1 && (blk[0] & ~iMask) == 0)
244 return -int(blk[0]);
245 else
246 throw "BigInteger operator int() const: Value is too big for an int";
247 default:
248 throw "BigInteger: Internal error";
252 BigInteger::operator unsigned short() const {
253 switch (sign) {
254 case zero:
255 return 0;
256 case positive:
257 if (len == 1 && (blk[0] & ~usMask) == 0)
258 return (unsigned short)(blk[0]);
259 else
260 throw "BigInteger operator unsigned short() const: Value is too big for an unsigned short";
261 case negative:
262 throw "BigInteger operator unsigned short() const: Cannot convert a negative integer to an unsigned type";
263 default:
264 throw "BigInteger: Internal error";
268 BigInteger::operator short() const {
269 switch (sign) {
270 case zero:
271 return 0;
272 case positive:
273 if (len == 1 && (blk[0] & ~sMask) == 0)
274 return short(blk[0]);
275 else
276 throw "BigInteger operator short() const: Value is too big for a short";
277 case negative:
278 if (len == 1 && (blk[0] & ~sMask) == 0)
279 return -short(blk[0]);
280 else
281 throw "BigInteger operator short() const: Value is too big for a short";
282 default:
283 throw "BigInteger: Internal error";
287 // COMPARISON
288 BigInteger::CmpRes BigInteger::compareTo(const BigInteger &x) const {
289 // A greater sign implies a greater number
290 if (sign < x.sign)
291 return less;
292 else if (sign > x.sign)
293 return greater;
294 else switch (sign) {
295 // If the signs are the same...
296 case zero:
297 return equal; // Two zeros are equal
298 case positive:
299 // Compare the magnitudes
300 return BigUnsigned::compareTo(x);
301 case negative:
302 // Compare the magnitudes, but return the opposite result
303 return CmpRes(-BigUnsigned::compareTo(x));
304 default:
305 throw "BigInteger: Internal error";
309 // PUT-HERE OPERATIONS
310 // These do some messing around to determine the sign of the result,
311 // then call one of BigUnsigned's put-heres.
313 // See remarks about aliased calls in BigUnsigned.cc .
314 #define DOTR_ALIASED(cond, op) \
315 if (cond) { \
316 BigInteger tmpThis; \
317 tmpThis.op; \
318 *this = tmpThis; \
319 return; \
322 // Addition
323 void BigInteger::add(const BigInteger &a, const BigInteger &b) {
324 DOTR_ALIASED(this == &a || this == &b, add(a, b));
325 // If one argument is zero, copy the other.
326 if (a.sign == zero)
327 operator =(b);
328 else if (b.sign == zero)
329 operator =(a);
330 // If the arguments have the same sign, take the
331 // common sign and add their magnitudes.
332 else if (a.sign == b.sign) {
333 sign = a.sign;
334 BigUnsigned::add(a, b);
335 } else {
336 // Otherwise, their magnitudes must be compared.
337 switch (a.BigUnsigned::compareTo(b)) {
338 // If their magnitudes are the same, copy zero.
339 case equal:
340 len = 0;
341 sign = zero;
342 break;
343 // Otherwise, take the sign of the greater, and subtract
344 // the lesser magnitude from the greater magnitude.
345 case greater:
346 sign = a.sign;
347 BigUnsigned::subtract(a, b);
348 break;
349 case less:
350 sign = b.sign;
351 BigUnsigned::subtract(b, a);
352 break;
357 // Subtraction
358 void BigInteger::subtract(const BigInteger &a, const BigInteger &b) {
359 // Notice that this routine is identical to BigInteger::add,
360 // if one replaces b.sign by its opposite.
361 DOTR_ALIASED(this == &a || this == &b, subtract(a, b));
362 // If a is zero, copy b and flip its sign. If b is zero, copy a.
363 if (a.sign == zero) {
364 BigUnsigned::operator =(b);
365 // Take the negative of _b_'s, sign, not ours.
366 // Bug pointed out by Sam Larkin on 2005.03.30.
367 sign = Sign(-b.sign);
368 } else if (b.sign == zero)
369 operator =(a);
370 // If their signs differ, take a.sign and add the magnitudes.
371 else if (a.sign != b.sign) {
372 sign = a.sign;
373 BigUnsigned::add(a, b);
374 } else {
375 // Otherwise, their magnitudes must be compared.
376 switch (a.BigUnsigned::compareTo(b)) {
377 // If their magnitudes are the same, copy zero.
378 case equal:
379 len = 0;
380 sign = zero;
381 break;
382 // If a's magnitude is greater, take a.sign and
383 // subtract a from b.
384 case greater:
385 sign = a.sign;
386 BigUnsigned::subtract(a, b);
387 break;
388 // If b's magnitude is greater, take the opposite
389 // of b.sign and subtract b from a.
390 case less:
391 sign = Sign(-b.sign);
392 BigUnsigned::subtract(b, a);
393 break;
398 // Multiplication
399 void BigInteger::multiply(const BigInteger &a, const BigInteger &b) {
400 DOTR_ALIASED(this == &a || this == &b, multiply(a, b));
401 // If one object is zero, copy zero and return.
402 if (a.sign == zero || b.sign == zero) {
403 sign = zero;
404 len = 0;
405 return;
407 // If the signs of the arguments are the same, the result
408 // is positive, otherwise it is negative.
409 sign = (a.sign == b.sign) ? positive : negative;
410 // Multiply the magnitudes.
411 BigUnsigned::multiply(a, b);
415 * DIVISION WITH REMAINDER
416 * Please read the comments before the definition of
417 * `BigUnsigned::divideWithRemainder' in `BigUnsigned.cc' for lots of
418 * information you should know before reading this function.
420 * Following Knuth, I decree that x / y is to be
421 * 0 if y==0 and floor(real-number x / y) if y!=0.
422 * Then x % y shall be x - y*(integer x / y).
424 * Note that x = y * (x / y) + (x % y) always holds.
425 * In addition, (x % y) is from 0 to y - 1 if y > 0,
426 * and from -(|y| - 1) to 0 if y < 0. (x % y) = x if y = 0.
428 * Examples: (q = a / b, r = a % b)
429 * a b q r
430 * === === === ===
431 * 4 3 1 1
432 * -4 3 -2 2
433 * 4 -3 -2 -2
434 * -4 -3 1 -1
436 void BigInteger::divideWithRemainder(const BigInteger &b, BigInteger &q) {
437 // Defend against aliased calls;
438 // same idea as in BigUnsigned::divideWithRemainder .
439 if (this == &q)
440 throw "BigInteger::divideWithRemainder: Cannot write quotient and remainder into the same variable";
441 if (this == &b || &q == &b) {
442 BigInteger tmpB(b);
443 divideWithRemainder(tmpB, q);
444 return;
447 // Division by zero gives quotient 0 and remainder *this
448 if (b.sign == zero) {
449 q.len = 0;
450 q.sign = zero;
451 return;
453 // 0 / b gives quotient 0 and remainder 0
454 if (sign == zero) {
455 q.len = 0;
456 q.sign = zero;
457 return;
460 // Here *this != 0, b != 0.
462 // Do the operands have the same sign?
463 if (sign == b.sign) {
464 // Yes: easy case. Quotient is zero or positive.
465 q.sign = positive;
466 } else {
467 // No: harder case. Quotient is negative.
468 q.sign = negative;
469 // Decrease the magnitude of the dividend by one.
470 BigUnsigned::operator --();
472 * We tinker with the dividend before and with the
473 * quotient and remainder after so that the result
474 * comes out right. To see why it works, consider the following
475 * list of examples, where A is the magnitude-decreased
476 * a, Q and R are the results of BigUnsigned division
477 * with remainder on A and |b|, and q and r are the
478 * final results we want:
480 * a A b Q R q r
481 * -3 -2 3 0 2 -1 0
482 * -4 -3 3 1 0 -2 2
483 * -5 -4 3 1 1 -2 1
484 * -6 -5 3 1 2 -2 0
486 * It appears that we need a total of 3 corrections:
487 * Decrease the magnitude of a to get A. Increase the
488 * magnitude of Q to get q (and make it negative).
489 * Find r = (b - 1) - R and give it the desired sign.
493 // Divide the magnitudes.
494 BigUnsigned::divideWithRemainder(b, q);
496 if (sign != b.sign) {
497 // More for the harder case (as described):
498 // Increase the magnitude of the quotient by one.
499 q.BigUnsigned::operator ++();
500 // Modify the remainder.
501 BigUnsigned temp(*this);
502 BigUnsigned::subtract(b, temp);
503 BigUnsigned::operator --();
506 // Sign of the remainder is always the sign of the divisor b.
507 sign = b.sign;
509 // Set signs to zero as necessary. (Thanks David Allen!)
510 if (len == 0)
511 sign = zero;
512 if (q.len == 0)
513 q.sign = zero;
515 // WHEW!!!
518 // Negation
519 void BigInteger::negate(const BigInteger &a) {
520 DOTR_ALIASED(this == &a, negate(a));
521 // Copy a's magnitude
522 BigUnsigned::operator =(a);
523 // Copy the opposite of a.sign
524 sign = Sign(-a.sign);
527 // INCREMENT/DECREMENT OPERATORS
529 // Prefix increment
530 void BigInteger::operator ++() {
531 switch (sign) {
532 case zero:
533 allocate(1);
534 sign = positive;
535 len = 1;
536 blk[0] = 1;
537 break;
538 case positive:
539 BigUnsigned::operator ++();
540 break;
541 case negative:
542 BigUnsigned::operator --();
543 if (len == 0)
544 sign = zero;
545 break;
549 // Postfix increment: same as prefix
550 void BigInteger::operator ++(int) {
551 operator ++();
554 // Prefix decrement
555 void BigInteger::operator --() {
556 switch (sign) {
557 case zero:
558 allocate(1);
559 sign = negative;
560 len = 1;
561 blk[0] = 1;
562 break;
563 case negative:
564 BigUnsigned::operator ++();
565 break;
566 case positive:
567 BigUnsigned::operator --();
568 if (len == 0)
569 sign = zero;
570 break;
574 // Postfix decrement: same as prefix
575 void BigInteger::operator --(int) {
576 operator --();